package com.huiquan.vocab.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.huiquan.analysis.domain.User;
import com.huiquan.framework.base.BaseService;
import com.huiquan.framework.base.ReturnCode;
import com.huiquan.framework.base.ReturnData;
import com.huiquan.framework.utils.DateUtils;
import com.huiquan.framework.utils.DateUtils.DateFormat;
import com.huiquan.framework.utils.ExcelUtil;
import com.huiquan.framework.utils.GetListUtil;
import com.huiquan.framework.utils.RespHeaderUtil;
import com.huiquan.framework.utils.ReturnUtil;
import com.huiquan.vocab.dao.VocabElementReasonClassDao;
import com.huiquan.vocab.dao.VocabElementReasonClassSexAgeDao;
import com.huiquan.vocab.domain.VocabElementReasonClassEntity;
import com.huiquan.vocab.domain.VocabElementReasonClassSexAge;
import com.huiquan.vocab.domain.VocabElementReasonClassVO;

/**
 * 原因词分类 service
 *
 * @author leo
 * @time 2017年7月19日 下午4:32:14
 */
@Service
public class VocabElementReasonClassService extends BaseService {

	@Autowired
	private VocabElementReasonClassDao dao;
	@Autowired
	private VocabElementReasonClassSexAgeDao sexAgeDao;

	public Map<String, Object> list(String startStr, String keyword, String exactSearchFlag, String countPerPageStr) {
		boolean exactFlag = exactSearchFlag != null && exactSearchFlag.equals("1");
		Map<String, Object> param = new HashMap<>();
		if (keyword != null && !keyword.isEmpty()) {
			param.put("vocabulary", exactFlag ? keyword : "%" + keyword + "%");
		}
		int totalSize = dao.selectListSize(param);
		// 获取翻页相关
		Map<String, Integer> pageNo = new HashMap<>();
		if (countPerPageStr != null && !countPerPageStr.isEmpty()) {
			int countPerPage = Integer.parseInt(countPerPageStr);
			pageNo = GetListUtil.getPageNoParam(totalSize, startStr, countPerPage);
			param.put("countPerPage", countPerPage);
		} else {
			pageNo = GetListUtil.getPageNoParam(totalSize, startStr);
		}
		int endPage = pageNo.get("endPage");
		int start = pageNo.get("start");
		int startIndex = pageNo.get("startIndex");
		List<VocabElementReasonClassVO> list = new ArrayList<>();
		if (startIndex < totalSize) {
			param.put("startIndex", startIndex);
			list = dao.selectList(param);
			for (VocabElementReasonClassVO vocabElement : list) {
				String[] sentence = getSentenceAndShowSentence(vocabElement.getSentence());
				vocabElement.setSentence(sentence[0]);
				vocabElement.setShowSentence(sentence[1]);
			}
		}
		Map<String, Object> map = GetListUtil.getReturnMap2(totalSize, start, startIndex, endPage, list, null);
		Map<String, String> showSearch = new LinkedHashMap<>();
		showSearch.put("keyword", "词语");
		map.put("showSearch", showSearch);
		if (countPerPageStr != null && !countPerPageStr.isEmpty()) {
			map.put("countPerPage", countPerPageStr);
		}
		return map;
	}

	/**
	 * 导出分类数据到excel
	 * 
	 * @param resp
	 * @throws IOException
	 */
	public void exportToExcel(HttpServletResponse resp, User user) throws IOException {
		// 导出前先做数据处理，为当前的标准词赋分类分级
		List<Map<String, Object>> dataList = dao.selectDataBeforeExport();
		if (dataList.size() > 0) {
			List<VocabElementReasonClassEntity> insertList = new ArrayList<>();
			VocabElementReasonClassEntity insertEntity = null;
			for (Map<String, Object> m : dataList) {
				String[] classNameGroup = String.valueOf(m.get("class_name_group")).split("\t");
				int classLevel = 0;
				for (String className : classNameGroup) {
					insertEntity = new VocabElementReasonClassEntity();
					insertEntity.setVid(Long.valueOf(m.get("vid").toString()));
					insertEntity.setClassName(className);
					insertEntity.setClassLevel(classLevel++);
					insertEntity.setModifierId(user.getUserId());
					insertEntity.setModifierName(user.getRealName());
					insertEntity.setDisable(m.get("disable") + "");
					insertList.add(insertEntity);
				}
			}
			dao.insertReasonClassBeforeExport(insertList);
		}
		OutputStream os = resp.getOutputStream();
		String fileName = "原因词分类" + "_" + DateUtils.convertDateFormat(new Date(), DateFormat.FULL_SECOND);
		// 设置respons的头信息
		RespHeaderUtil.setXlsxResp(resp, fileName);
		Workbook workbook = new XSSFWorkbook();// 创建文档
		Sheet sheet = workbook.createSheet("原因词分类"); // 创建Sheet
		Row firstRow = sheet.createRow(0); // 首行
		ExcelUtil.setCell(firstRow, 0, "1symptom");
		ExcelUtil.setCell(firstRow, 1, "sentence");
		ExcelUtil.setCell(firstRow, 2, "0分类");
		ExcelUtil.setCell(firstRow, 3, "2分类");
		ExcelUtil.setCell(firstRow, 4, "3分类");
		ExcelUtil.setCell(firstRow, 5, "disable");
		int i = 1;
		Row row = null;
		String[] classGroup = null;
		Map<String, Object> param = new HashMap<>();
		List<VocabElementReasonClassVO> list = dao.selectList(param);
		for (VocabElementReasonClassVO entity : list) {
			row = sheet.createRow(i++);
			int j = 0;
			ExcelUtil.setCell(row, j++, entity.getVocabulary());
			ExcelUtil.setCell(row, j++, entity.getSentence());
			if (StringUtils.isNotEmpty(entity.getClassNameGroup())) {
				classGroup = entity.getClassNameGroup().split("\t");
				for (String s : classGroup) {
					ExcelUtil.setCell(row, j++, s);
				}
			}
			// 如果没有第三类 则空出来
			if (j == 4) {
				ExcelUtil.setCell(row, j++, "");
			}
			ExcelUtil.setCell(row, j++, entity.getDisable());
		}
		// 设置筛选框
		CellRangeAddress c = CellRangeAddress.valueOf("A1:E1");
		sheet.setAutoFilter(c);
		// 设置列宽
		sheet.setColumnWidth(0, 26 * 256);
		sheet.setColumnWidth(1, 84 * 256);
		sheet.setColumnWidth(2, 13 * 256);
		sheet.setColumnWidth(3, 13 * 256);
		sheet.setColumnWidth(4, 13 * 256);
		workbook.write(os);
		workbook.close();
	}

	/**
	 * 导入分类数据
	 * 
	 * @param file
	 * @param user
	 * @return
	 * @throws IOException
	 */
	public ReturnData importFromExcel(MultipartFile file, User user) throws IOException {
		InputStream inputStream = null;
		Workbook workbook = null;
		try {
			// 获取文件流，解析文件
			inputStream = file.getInputStream();
			workbook = new XSSFWorkbook(inputStream);
			Sheet sheet = workbook.getSheetAt(0);
			// 从excel中读取得到数据列表
			List<Map<String, Object>> list = new ArrayList<>();
			Map<String, Object> map = null;
			int disableTemp = 4;
			for (Row row : sheet) {
				if (row.getRowNum() == 0) {
					if (StringUtils.equals(getCell(row, 4), "3分类")) {
						disableTemp = 5;
					}
					continue;
				}
				String disable = getCell(row, disableTemp);
				if (StringUtils.isBlank(disable) || !StringUtils.isNumeric(disable)) {
					ReturnCode returnCode = ReturnCode.DYNAMIC_DESC_EXCEPTION;
					returnCode.setDesc("有效性必须填写");
					return ReturnUtil.fail(returnCode);
				}
				int j = 0;
				while (row.getCell(0) != null && row.getCell(j + 2) != null && (j + 2) < disableTemp) {
					if (StringUtils.isNotBlank(getCell(row, j + 2))) {
						map = new HashMap<>();
						map.put("vocabulary", getCell(row, 0));
						map.put("name", getCell(row, j + 2));
						map.put("disable", disable);
						map.put("level", j);
						list.add(map);
					}
					j++;
				}
			}
			// 把数据插入到临时表中;
			dao.initReasonClassTempTable(list);
			// 开始校验数据
			// 判断excel中的原因词在element表中是否都存在
			int checkCount = dao.selectCheckCount();
			if (checkCount > 0) {
				StringBuilder message = new StringBuilder("导入失败！错误数据为:");
				List<String> checkList = dao.selectCheckList();
				for (String str : checkList) {
					message.append("\n").append(str);
				}
				return ReturnUtil.customMessage(message.toString());
			}
			dao.importTempData(user.getUserId(), user.getRealName());
		} catch (Exception e) {
			throw e;
		} finally {
			workbook.close();
			inputStream.close();
		}
		return ReturnUtil.success();
	}

	private String getCell(Row row, int num) {
		if (row != null) {
			row.getCell(num).setCellType(Cell.CELL_TYPE_STRING);
			return row.getCell(num).getStringCellValue();
		} else {
			return "";
		}
	}

	/**
	 * 根据例句获取在列表上展现的例句内容
	 * 
	 * @param value
	 * @return
	 */
	private String[] getSentenceAndShowSentence(String value) {
		// 例句的分隔符
		char sentenceSegmentFlag = 3;
		// 例句的频数分割符号
		char countSegmentFlag = 4;
		String[] sentences = value.split("\\" + sentenceSegmentFlag);
		StringBuffer sentence = new StringBuffer();
		for (int i = 0; i < sentences.length; i++) {
			// 去除例句频数
			String[] sentenceAndCount = sentences[i].split("\\" + countSegmentFlag);
			sentences[i] = sentenceAndCount[0];
			sentence.append(sentences[i]);
			if (i != (sentences.length - 1)) {
				sentence.append("\n");
			}
		}
		return new String[] { sentence.toString(), sentences[0] };
	}

	public ReturnData refresh() {

		dao.insertByStd();

		return ReturnUtil.success();
	}

	public ModelAndView elementSexAgeList(String startStr, String keyword, Integer status, String exactSearchFlag,
			String countPerPageStr) {
		boolean exactFlag = exactSearchFlag != null && exactSearchFlag.equals("1");

		Map<String, Object> param = new HashMap<>();
		if (keyword != null && !keyword.isEmpty()) {
			param.put("className", exactFlag ? keyword : "%" + keyword + "%");
		}
		param.put("checkFlag", status);

		int totalSize = sexAgeDao.retrieveSize(param);

		Map<String, Integer> pageNo;
		if (countPerPageStr != null && !countPerPageStr.isEmpty()) {
			int countPerPage = Integer.parseInt(countPerPageStr);
			pageNo = GetListUtil.getPagingParam(totalSize, startStr, countPerPage);
		} else {
			pageNo = GetListUtil.getPagingParam(totalSize, startStr);
		}
		param.put("countPerPage", pageNo.get("countPerPage"));
		int startIndex = pageNo.get("startIndex");

		List<VocabElementReasonClassSexAge> list = new ArrayList<>();

		if (startIndex < totalSize) {
			param.put("startIndex", startIndex);
			list = sexAgeDao.retrieveList(param);
		}

		Map<String, Object> map = new HashMap<>();
		map.putAll(pageNo);
		map.put("list", list);

		Map<String, String> showSearch = new LinkedHashMap<>();
		showSearch.put("keyword", "分类名称");
		map.put("showSearch", showSearch);

		return new ModelAndView("vocab/element_index", map);
	}

	public ReturnData setSex(String id, String sex, User user) {
		sexAgeDao.setSex(id, sex, user);
		return ReturnUtil.success();
	}

	public ReturnData setAge(String id, String age, Boolean flag, User user) {
		VocabElementReasonClassSexAge sa = sexAgeDao.retrieveObjectById(Long.parseLong(id));

		if (flag) {
			// flag为true则添加该年龄段
			if (sa.getAge() == null || sa.getAge().indexOf(age) < 0) {
				age = (sa.getAge() == null ? "" : sa.getAge()) + age + ";";
			}
		} else {
			// flag为true则去除该年龄段
			if (sa.getAge() != null) {
				age = sa.getAge().replace(age + ";", "");
			}
		}
		sexAgeDao.setAge(id, age, user);
		return ReturnUtil.success();
	}

	public ReturnData submitSexAge(String ids, User user) {
		if (ids != null && !ids.isEmpty()) {
			if (ids.lastIndexOf(",") == ids.length() - 1) {
				ids = ids.substring(0, ids.length() - 1);
			}
			sexAgeDao.submitSexAge(ids, user);
		}
		return ReturnUtil.success();
	}
	
	public void initSexAge() {
		sexAgeDao.init();
	}

}
